package com.onion.orm.utils;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.apache.commons.lang3.StringUtils;

import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ColumnUtil {

    /**
     * 用来识别内容中包括的列名替换位
     * <p>
     * "@__self__@" <br>
     * "@parentId@"
     */
    private final static Pattern patternFieldNamePlaceHolder = Pattern.compile("@([a-zA-Z0-9_-]+)@");

    private static Cache<Class<?>, Map<String, String>> fieldsNameCache = Caffeine.newBuilder().maximumSize(5_000).
                    expireAfterWrite(1800, TimeUnit.SECONDS).build(
/*                        new CacheLoader<Class<?>, Map<String, String>>() {
                            @Override
                            public Map<String, String> load(Class<?> cls) throws Exception {
                                if (cls == null) {
                                    return null;
                                }
                                Map<String, String> fieldNameMap = Maps.newConcurrentMap();
                                Field[] fields = cls.getDeclaredFields();
                                for (Field field : fields) {
                                    String fieldName = field.getName();
                                    if (fieldName.equals("serialVersionUID")) {
                                        continue;
                                    }
                                    if (field.isAnnotationPresent(IgnoreKey.class)) {
                                        continue;
                                    }
                                    String propertyName = StringHelper.toCamel(fieldName);
                                    String columnName = StringHelper.toUnderline(fieldName);
                                    fieldNameMap.put(propertyName, columnName);
                                }
                                return fieldNameMap;
                            }
                        }*/
    );

    /**
     * 根据给定的类对字符串中可能存在的替换位做替换
     * @param self  当前的属性名
     * @param str   待解析的字符串
     * @param clz   所属的类
     * @return
     */
    public static String parseColumnNames(String self, String str, Class<?> clz) {
        if (StringUtils.isEmpty(str) || !str.contains("@")) {
            return str;
        }
        Matcher matcher = patternFieldNamePlaceHolder.matcher(str);
        StringBuffer sb = new StringBuffer();
        Map<String, String> fieldsMapping;
        try {
            fieldsMapping = fieldsNameCache.getIfPresent(clz);
        } catch (Exception e) {
            throw new RuntimeException("解析替换位时出错", e);
        }

        while (matcher.find()) {
            String fieldName = matcher.group(1);
            if (fieldName.equals("__self__")) {
                if (StringUtils.isEmpty(self)) {
                    throw new RuntimeException("没有指定当前属性名");
                }
                //对self特殊处理
                fieldName = self;
            }
            if (fieldsMapping.containsKey(fieldName)) {
                // found field, replace
                matcher.appendReplacement(sb, String.format("`%s`", fieldsMapping.get(fieldName)));
            }
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

}